import React, { createContext, useContext, useReducer } from 'react';
import type { CameraSource, CameraPlayerState } from '@/types/camera';
import { set } from 'lodash';

interface CameraPlayerContextType {
    state: CameraPlayerState;
    setPlayer: (player: any) => void;
    setSelectedIndex: (index: number) => void;
    addVideo: (source: CameraSource) => void;
    togglePlayer: () => void;
    updatePosition: (x: number, y: number) => void;
}

const CameraPlayerContext = createContext<CameraPlayerContextType | undefined>(undefined);

type CameraAction =
    | { type: 'SET_PLAYER'; payload: any }
    | { type: 'SET_SELECTED_INDEX'; payload: number }
    | { type: 'ADD_VIDEO'; payload: CameraSource }
    | { type: 'REMOVE_VIDEO'; payload: string }
    | { type: 'PLAY_VIDEO'; payload: string }
    | { type: 'TOGGLE_PLAYER' }
    | { type: 'UPDATE_POSITION'; payload: { x: number; y: number } };

const initialState: CameraPlayerState = {
    player: null,
    visible: false,
    selectedIndex: 0,
    position: { x: 100, y: 100 },
    currentSource: null,
    playlist: [],
    isPlaying: false
};

function CameraReducer(state: CameraPlayerState, action: CameraAction): CameraPlayerState {
    switch (action.type) {
        case 'SET_PLAYER':
            set(window, 'hikPlayer', action.payload);
            return { ...state, player: action.payload };

        case 'SET_SELECTED_INDEX':
            return { ...state, selectedIndex: action.payload };

        case 'ADD_VIDEO':
            const exists = state.playlist.find(v => v.id === action.payload.id);
            if (exists) {
                return { ...state, currentSource: action.payload };
            }
            return {
                ...state,
                playlist: [...state.playlist, action.payload],
                currentSource: action.payload,
                visible: true
            };

        case 'REMOVE_VIDEO':
            const filteredPlaylist = state.playlist.filter(v => v.id !== action.payload);
            const newCurrent = state.currentSource?.id === action.payload ?
                filteredPlaylist[0] || null : state.currentSource;
            return {
                ...state,
                playlist: filteredPlaylist,
                currentSource: newCurrent,
                visible: filteredPlaylist.length > 0
            };

        case 'PLAY_VIDEO':
            const sourceToPlay = state.playlist.find(v => v.id === action.payload);
            return sourceToPlay ? { ...state, currentSource: sourceToPlay, visible: true } : state;

        case 'TOGGLE_PLAYER':
            return { ...state, visible: !state.visible };

        case 'UPDATE_POSITION':
            return { ...state, position: action.payload };

        default:
            return state;
    }
}

export const CameraPlayerProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {
    const [state, dispatch] = useReducer(CameraReducer, initialState);

    const setPlayer = (player: any) => dispatch({ type: 'SET_PLAYER', payload: player });
    const setSelectedIndex = (index: number) => dispatch({ type: 'SET_SELECTED_INDEX', payload: index });
    const addVideo = (source: CameraSource) => dispatch({ type: 'ADD_VIDEO', payload: source });
    const togglePlayer = () => dispatch({ type: 'TOGGLE_PLAYER' });
    const updatePosition = (x: number, y: number) => dispatch({ type: 'UPDATE_POSITION', payload: { x, y } });

    return (
        <CameraPlayerContext.Provider value={{
            state,
            setPlayer,
            setSelectedIndex,
            addVideo,
            togglePlayer,
            updatePosition
        }}>
            {children}
        </CameraPlayerContext.Provider>
    );
};

export const useCameraPlayer = () => {
    const context = useContext(CameraPlayerContext);
    if (!context) throw new Error('useCameraPlayer must be used within CameraPlayerProvider');
    return context;
};